home *** CD-ROM | disk | FTP | other *** search
- "ILBM" IFF Interleaved Bitmap
-
- Date: January 17, 1986
- From: Jerry Morrison, Electronic Arts
- Status: Released and in use
-
- 1. Introduction
-
- "EA IFF 85" is Electronic Arts' standard for interchange format files.
- "ILBM" is a format for a 2 dimensional raster graphics image, specifically
- an InterLeaved bitplane BitMap image with color map. An ILBM is an
- IFF "data section" or "FORM type", which can be an IFF file or a part
- of one. (See the IFF reference.)
-
- An ILBM is an archival representation designed for three uses. First,
- a standalone image that specifies exactly how to display itself (resolution,
- size, color map, etc.). Second, an image intended to be merged into
- a bigger picture which has its own depth, color map, and so on. And
- third, an empty image with a color map selection or "palette" for
- a paint program. ILBM is also intended as a building block for composite
- IFF FORMs like "animation sequence" and "structured graphics". Some
- uses of ILBM will be to preserve as much information as possible across
- disparate environments. Other uses will be to store data for a single
- program or highly cooperative programs while maintaining subtle details.
- So we're trying to accomplish a lot with this one format.
-
- This memo is the IFF supplement for FORM ILBM. Section 2 defines the
- purpose and format of property chunks bitmap header "BMHD", color
- map "CMAP", hotspot "GRAB", destination merge data "DEST", sprite
- information "SPRT", and Commodore Amiga viewport mode "CAMG". Section
- 3 defines the standard data chunk "BODY". These are the "standard"
- chunks. Section 4 defines the nonstandard color range data chunk "CRNG".
- Additional specialized chunks like texture pattern can be added later.
- The ILBM syntax is summarized in Appendix A as a regular expression
- and in Appendix B as a box diagram. Appendix C explains the optional
- run encoding scheme. Appendix D names the committee responsible for
- this FORM ILBM standard.
-
- Details of the raster layout are given in part 3, "Standard Data Chunk".
- Some elements are based on the Commodore Amiga hardware but generalized
- for use on other computers. An alternative to ILBM would be appropriate
- for computers with true color data in each pixel.
-
- Reference:
-
- "EA IFF 85" Standard for Interchange Format Files describes the underlying
- conventions for all IFF files.
-
- Amiga[tm] is a trademark of Commodore-Amiga, Inc.
- Electronic Arts[tm] is a trademark of Electronic Arts.
- Macintosh[tm] is a trademark licensed to Apple Computer, Inc.
- MacPaint[tm] is a trademark of Apple Computer, Inc.
-
-
- 2. Standard Properties
-
- The required property "BMHD" and any optional properties must appear
- before any "BODY" chunk. (Since an ILBM has only one BODY chunk, any
- following properties are superfluous.) Any of these properties may
- be shared over a LIST of FORMs IBLM by putting them in a PROP ILBM.
- (See the "EA IFF 85" memo.)
-
- BMHD
-
- The required property "BMHD" holds a BitMapHeader as defined in these
- C declarations and following documentation. It describes the dimensions
- and encoding of the image, including data necessary to understand
- the BODY chunk to follow.
-
- typedef UBYTE Masking; /* Choice of masking technique. */
-
- #define mskNone 0
- #define mskHasMask 1
- #define mskHasTransparentColor 2
- #define mskLasso 3
-
- typedef UBYTE Compression;
- /* Choice of compression algorithm applied to the rows of all
- * source and mask planes. "cmpByteRun1" is the byte run encoding
- * described in Appendix C. Do not compress across rows! */
- #define cmpNone 0
- #define cmpByteRun1 1
-
- typedef struct {
- UWORD w, h; /* raster width & height in pixels */
- WORD x, y; /* pixel position for this image */
- UBYTE nPlanes; /* # source bitplanes */
- Masking masking;
- Compression compression;
- UBYTE pad1; /* unused; for consistency, put 0 here */
- UWORD transparentColor; /* transparent "color number" (sort of) */
- UBYTE xAspect, yAspect; /* pixel aspect, a ratio width : height */
- WORD pageWidth, pageHeight; /* source "page" size in pixels */
- } BitMapHeader;
-
- Fields are filed in the order shown. The UBYTE fields are byte-packed.
-
- The fields w and h indicate the size of the image rectangle in pixels.
- Each row of the image is stored in an integral number of 16 bit words.
- The number of words per row is Ceiling(w/16). The fields x and y indicate
- the desired position of this image within the destination picture.
- Some reader programs may ignore x and y. A safe default for writing
- an ILBM is (x, y) = (0, 0).
-
- The number of source bitplanes in the BODY chunk (see below) is stored
- in nPlanes. An ILBM with a CMAP but no BODY and nPlanes = 0 is the
- recommended way to store a color map.
-
- Note: Color numbers are color map index values formed by pixels in
- the destination bitmap, which may be deeper than nPlanes if a DEST
- chunk calls for merging the image into a deeper image.
-
- The field masking indicates what kind of masking is to be used for
- this image. The value mskNone designates an opaque rectangular image.
- The value mskHasMask means that a mask plane is interleaved with the
- bitplanes in the BODY chunk (see below). The value mskHasTransparentColor
- indicates that pixels in the source planes matching transparentColor
- are to be considered "transparent". (Actually, transparentColor isn't
- a "color number" since it's matched with numbers formed by the source
- bitmap rather than the possibly deeper destination bitmap. Note that
- having a transparent color implies ignoring one of the color registers.
- See CMAP, below.) The value mskLasso indicates the reader may construct
- a mask by lassoing the image as in MacPaint*. To do this, put a 1
- pixel border of transparentColor around the image rectangle. Then
- do a seed fill from this border. Filled pixels are to be transparent.
-
- Issue: Include in an appendix an algorithm for converting a transparent
- color to a mask plane, and maybe a lasso algorithm.
-
- A code indicating the kind of data compression used is stored in compression.
- Beware that using data compression makes your data unreadable by programs
- that don't implement the matching decompression algorithm. So we'll
- employ as few compression encodings as possible. The run encoding
- byteRun1 is documented in Appendix C, below.
-
- The field pad1 is a pad byte and must be set to 0 for consistency.
- This field could get used in the future.
-
- The transparentColor specifies which bit pattern means "transparent".
- This only applies if masking is mskHasTransparentColor or mskLasso
- (see above). Otherwise, transparentColor should be 0.
-
- The pixel aspect ratio is stored as a ratio in the two fields xAspect
- and yAspect. This may be used by programs to compensate for different
- aspects or to help interpret the fields w, h, x, y, pageWidth, and
- pageHeight, which are in units of pixels. The fraction xAspect/yAspect
- represents a pixel's width/height. It's recommended that your programs
- store proper fractions in BitMapHeaders, but aspect ratios can always
- be correctly compared with the the test
-
- xAspect%yDesiredAspect = yAspect%xDesiredAspect
-
- Typical values for aspect ratio are width : height = 10 : 11 (Amiga
- 320 x 200 display) and 1 : 1 (Macintosh*).
-
- The size in pixels of the source "page" (any raster device) is stored
- in pageWidth and pageHeight, e.g. (320, 200) for a low resolution
- Amiga display. This information might be used to scale an image or
- to automatically set the display format to suit the image. (The image
- can be larger than the page.)
-
- CMAP
-
- The optional (but encouraged) property "CMAP" stores color map data
- as triplets of red, green, and blue intensity values. The n color
- map entries ("color registers") are stored in the order 0 through
- n-1, totaling 3n bytes. Thus n is the ckSize/3. Normally, n would
- equal 2nPlanes.
-
- A CMAP chunk contains a ColorMap array as defined below. (These typedefs
- assume a C compiler that implements packed arrays of 3-byte elements.)
-
- typedef struct {
- UBYTE red, green, blue; /* color intensities 0..255 */
- } ColorRegister; /* size = 3 bytes */
-
- typedef ColorRegister ColorMap[n]; /* size = 3n bytes */
-
- The color components red, green, and blue represent fractional intensity
- values in the range 0 through 255 256ths. White is (255, 255, 255)
- and black is (0, 0, 0). If your machine has less color resolution,
- use the high order bits. Shift each field right on reading (or left
- on writing) and assign it to (from) a field in a local packed format
- like Color4, below. This achieves automatic conversion of images across
- environments with different color resolutions. On reading an ILBM,
- use defaults if the color map is absent or has fewer color registers
- than you need. Ignore any extra color registers.
-
- The example type Color4 represents the format of a color register
- in working memory of an Amiga computer, which has 4 bit video DACs.
- (The ":4" tells the C compiler to pack the field into 4 bits.)
-
- typedef struct {
- unsigned pad1 :4, red :4, green :4, blue :4;
- } Color4; /* Amiga RAM format. Not filed. */
-
- Remember that every chunk must be padded to an even length, so a color
- map with an odd number of entries would be followed by a 0 byte, not
- included in the ckSize.
-
- GRAB
-
- The optional property "GRAB" locates a "handle" or "hotspot" of the
- image relative to its upper left corner, e.g. when used as a mouse
- cursor or a "paint brush". A GRAB chunk contains a Point2D.
-
- typedef struct {
- WORD x, y; /* relative coordinates (pixels) */
- } Point2D;
-
- DEST
-
- The optional property "DEST" is a way to say how to scatter zero or
- more source bitplanes into a deeper destination image. Some readers
- may ignore DEST.
-
- The contents of a DEST chunk is DestMerge structure:
-
- typedef struct {
- UBYTE depth; /* # bitplanes in the original source */
- UBYTE pad1; /* unused; for consistency put 0 here */
- UWORD planePick; /* how to scatter source bitplanes into destination */
- UWORD planeOnOff; /* default bitplane data for planePick */
- UWORD planeMask; /* selects which bitplanes to store into */
- } DestMerge;
-
- The low order depth number of bits in planePick, planeOnOff, and planeMask
- correspond one-to-one with destination bitplanes. Bit 0 with bitplane
- 0, etc. (Any higher order bits should be ignored.) "1" bits in planePick
- mean "put the next source bitplane into this bitplane", so the number
- of "1" bits should equal nPlanes. "0" bits mean "put the corresponding
- bit from planeOnOff into this bitplane". Bits in planeMask gate writing
- to the destination bitplane: "1" bits mean "write to this bitplane"
- while "0" bits mean "leave this bitplane alone". The normal case (with
- no DEST property) is equivalent to planePick = planeMask = 2nPlanesJ-
- 1.
-
- Remember that color numbers are formed by pixels in the destination
- bitmap (depth planes deep) not in the source bitmap (nPlanes planes
- deep).
-
- SPRT
-
- The presence of an "SPRT" chunk indicates that this image is intended
- as a sprite. It's up to the reader program to actually make it a sprite,
- if even possible, and to use or overrule the sprite precedence data
- inside the SPRT chunk:
-
- typedef UWORD SpritePrecedence; /* relative precedence, 0 is the highest */
-
- Precedence 0 is the highest, denoting a sprite that is foremost.
-
- Creating a sprite may imply other setup. E.g. a 2 plane Amiga sprite
- would have transparentColor = 0. Color registers 1, 2, and 3 in the
- CMAP would be stored into the correct hardware color registers for
- the hardware sprite number used, while CMAP color register 0 would
- be ignored.
-
- CAMG
-
- A "CAMG" chunk is specifically for the Commodore Amiga computer. It
- stores a LONG "viewport mode". This lets you specify Amiga display
- modes like "dual playfield" and "hold and modify".
- 3. Standard Data Chunk
-
- Raster Layout
-
- Raster scan proceeds left-to-right (increasing X) across scan lines,
- then top-to-bottom (increasing Y) down columns of scan lines. The
- coordinate system is in units of pixels, where (0,0) is the upper
- left corner.
-
- The raster is typically organized as bitplanes in memory. The corresponding
- bits from each plane, taken together, make up an index into the color
- map which gives a color value for that pixel. The first bitplane,
- plane 0, is the low order bit of these color indexes.
-
- A scan line is made of one "row" from each bitplane. A row is one
- planesU bits for one scan line, but padded out to a word (2 byte)
- boundary (not necessarily the first word boundary). Within each row,
- successive bytes are displayed in order and the most significant bit
- of each byte is displayed first.
-
- A "mask" is an optional "plane" of data the same size (w, h) as a
- bitplane. It tells how to "cut out" part of the image when painting
- it onto another image."One" bits in the mask mean "copy the corresponding
- pixel to the destination" while "zero" mask bits mean "leave this
- destination pixel alone". In other words, "zero" bits designate transparent
- pixels.
-
- The rows of the different bitplanes and mask are interleaved in the
- file (see below). This localizes all the information pertinent to
- each scan line. It makes it much easier to transform the data while
- reading it to adjust the image size or depth. It also makes it possible
- to scroll a big image by swapping rows directly from the file without
- random-accessing to all the bitplanes.
-
- BODY
-
- The source raster is stored in a "BODY" chunk. This one chunk holds
- all bitplanes and the optional mask, interleaved by row.
-
- The BitMapHeader, in a BMHD property chunk, specifies the raster's
- dimensions w, h, and nPlanes. It also holds the masking field which
- indicates if there is a mask plane and the compression field which
- indicates the compression algorithm used. This information is needed
- to interpret the BODY chunk, so the BMHD chunk must appear first.
- While reading an ILBM's BODY, a program may convert the image to another
- size by filling (with transparentColor) or clipping.
-
- The BODY's content is a concatenation of scan lines. Each scan line
- is a concatenation of one row of data from each plane in order 0 through
- nPlanes-1 followed by one row from the mask (if masking = hasMask
- ). If the BitMapHeader field compression is cmpNone, all h rows are
- exactly Ceiling(w/16) words wide. Otherwise, every row is compressed
- according to the specified algorithm and their stored widths depend
- on the data compression.
-
- Reader programs that require fewer bitplanes than appear in a particular
- ILBM file can combine planes or drop the high-order (later) planes.
- Similarly, they may add bitplanes and/or discard the mask plane.
-
- Do not compress across rows and don't forget to compress the mask
- just like the bitplanes. Remember to pad any BODY chunk that contains
- an odd number of bytes.
- 4. Nonstandard Data Chunk
-
- The following data chunk was defined after various programs began
- using FORM ILBM so it's a "nonstandard" chunk. That means there's
- some slight chance of name collisions.
-
- CRNG
-
- A "CRNG" chunk contains "color register range" information. It's used
- by Electronic Arts' Deluxe Paint program to identify a contiguous
- range of color registers for a "shade range" and color cycling. There
- can be zero or more CRNG chunks in an ILBM, but all should appear
- before the BODY chunk. Deluxe Paint normally writes 4 CRNG chunks
- in an ILBM when the user asks it to "Save Picture".
-
- typedef struct {
- WORD pad1; /* reserved for future use; store 0 here */
- WORD rate; /* color cycle rate */
- WORD active; /* nonzero means cycle the colors */
- UBYTE low, high; /* lower and upper color registers selected */
- } CRange;
-
- The fields low and high indicate the range of color registers (color
- numbers) selected by this CRange.
-
- The field active indicates whether color cycling is on or off. Zero
- means off.
-
- The field rate determines the speed at which the colors will step
- when color cycling is on. The units are such that a rate of 60 steps
- per second is represented as 214 = 16384. Slower rates can be obtained
- by linear scaling: for 30 steps/second, rate = 8192; for 1 step/second,
- rate = 16384/60 E 273.
-
- CCRT
-
- Commodore's Graphicraft program uses a similar chunk "CCRT" (for Color
- Cyling Range and Timing). This chunk contains a CycleInfo structure.
-
- typedef struct {
- WORD direction; /* 0 = don't cycle. 1 = cycle forwards (1, 2, 3).
- * -1 = cycle backwards (3, 2, 1) */
- UBYTE start, end; /* lower and upper color registers selected */
- LONG seconds; /* # seconds between changing colors */
- LONG microseconds; /* # microseconds between changing colors */
- WORD pad; /* reserved for future use; store 0 here */
- } CycleInfo;
-
- This is pretty similar to a CRNG chunk. A program would probably only
- use one of these two methods of expressing color cycle data. You could
- write out both if you want to communicate this information to both
- Deluxe Paint and Graphicraft.
-
- A CCRT chunk expresses the color cycling rate as a number of seconds
- plus a number of microseconds.
-
-
-
- Appendix A. ILBM Regular Expression
-
- Here's a regular expression summary of the FORM ILBM syntax. This
- could be an IFF file or a part of one.
-
- ILBM ::= "FORM" #{ "ILBM" BMHD [CMAP] [GRAB] [DEST] [SPRT] [CAMG]
- CRNG* CCRT* [BODY] }
-
- BMHD ::= "BMHD" #{ BitMapHeader }
- CMAP ::= "CMAP" #{ (red green blue)* } [0]
- GRAB ::= "GRAB" #{ Point2D }
- DEST ::= "DEST" #{ DestMerge }
- SPRT ::= "SPRT" #{ SpritePrecendence }
- CAMG ::= "CAMG" #{ LONG }
-
- CRNG ::= "CRNG" #{ CRange }
- CCRT ::= "CCRT" #{ CycleInfo }
- BODY ::= "BODY" #{ UBYTE* } [0]
-
- The token "#" represents a ckSize LONG count of the following {braced}
- data bytes. E.g. a BMHD's "#" should equal sizeof(BitMapHeader). Literal
- strings are shown in "quotes", [square bracket items] are optional,
- and "*" means 0 or more repetitions. A sometimes-needed pad byte is
- shown as "[0]".
-
- The property chunks (BMHD, CMAP, GRAB, DEST, SPRT, and CAMG) and any
- CRNG and CCRT data chunks may actually be in any order but all must
- appear before the BODY chunk since ILBM readers usually stop as soon
- as they read the BODY. If any of the 6 property chunks are missing,
- default values are "inherited" from any shared properties (if the
- ILBM appears inside an IFF LIST with PROPs) or from the reader program's
- defaults. If any property appears more than once, the last occurrence
- before the BODY is the one that counts since that's the one that modifies
- the BODY.
-
-
-
- Appendix B. ILBM Box Diagram
-
- Here's a box diagram for a simple example: an uncompressed image 320
- x 200 pixels x 3 bitplanes. The text to the right of the diagram shows
- the outline that would be printed by the IFFCheck utility program
- for this particular file.
-
-
- +-----------------------------------+
- |'FORM' 24070 | FORM 24070 IBLM
- +-----------------------------------+
- |'ILBM' |
- +-----------------------------------+
- | +-------------------------------+ |
- | | 'BMHD' 20 | | .BMHD 20
- | | 320, 200, 0, 0, 3, 0, 0, ... | |
- | + ------------------------------+ |
- | | 'CMAP' 21 | | .CMAP 21
- | | 0, 0, 0; 32, 0, 0; 64,0,0; .. | |
- | +-------------------------------+ |
- | 0 |
- +-----------------------------------+
- |'BODY' 24000 | .BODY 24000
- |0, 0, 0, ... |
- +-----------------------------------+
-
-
-
- The "0" after the CMAP chunk is a pad byte.
-
-
-
- Appendix C. ByteRun1 Run Encoding
-
- The run encoding scheme byteRun1 is best described by psuedo code
- for the decoder Unpacker (called UnPackBits in the Macintosh* toolbox):
-
- UnPacker:
- LOOP until produced the desired number of bytes
- Read the next source byte into n
- SELECT n FROM
- [0..127] => copy the next n+1 bytes literally
- [-1..-127] => replicate the next byte -n+1 times
- -128 => noop
- ENDCASE;
- ENDLOOP;
-
- In the inverse routine Packer, it's best to encode a 2 byte repeat
- run as a replicate run except when preceded and followed by a literal
- run, in which case it's best to merge the three into one literal run.
- Always encode 3 byte repeats as replicate runs.
-
- Remember that each row of each scan line of a raster is separately
- packed.
-
-
-
- Appendix D. Standards Committee
-
- The following people contributed to the design of this FORM ILBM standard:
-
- Bob "Kodiak" Burns, Commodore-Amiga
- R. J. Mical, Commodore-Amiga
- Jerry Morrison, Electronic Arts
- Greg Riker, Electronic Arts
- Steve Shaw, Electronic Arts
- Dan Silva, Electronic Arts
- Barry Walsh, Commodore-Amiga
-